//----------------------------------------------------------------------
//-  NOTE: ALL INSIDE /** **/ IS NOT TRANSLATED YET!                   -
//-        THIS INCLUDES ALL THOSE "OUT &XXXXX" STUFF!                 -
//----------------------------------------------------------------------//

//DISCLAIMER: USE AT YOUR OWN RISK. NO SUPPORT. NOT WORKING AND OVERALL, MAY BE DANGEROUS.
//NOTE 2: THE CURRENT CODE IS INCOMPLETE BUT IT WILL COMPILE FINE!
//NOTE 3: IF YOU COMPILE AS IS, YOU ARE GOING TO HAVE AN "ARRAY OUT OF BOUNDS" ERROR. OF COURSE.
//NOTE 4: CONTRACT PROGRAMMING AND ASSERTS NOT USED FOR OBVIOUS REASONS.
//NOTE 5: HAVE FUN, IF YOU DONT EXPLODE YOUR PC FIRST... OK I AM JOKING.

import std.stdio : write;
import std.math : sqrt;
import std.math : cos;
import std.math : sin;

int main(char[][] args) {
    translated();
    return 0;
}

//BELOW IS THE "TRANSLATED()" FUNCTION.
//THIS FUNCTION IS ACTUALLY WHAT "SHOULD" BE KEN SILVERMAN'S VOXEL DEMO CODE.
//(correction: seems like someone updated the page with voxlap source and I never seen it?)
//(might as well start again from there -------------------------/\)
//THE PROBLEM IS THAT THE SOURCE CODE GIVEN WAS WRITTEN IN BASIC.
//I HAVE NO CLUE OF BASIC LANGUAGE SO EVERYTHING DOWN HERE IS BASED ON ASSUMPTIONS.
//
//MOREOVER, THIS CODE IS PROBABLY FOR DOS, 16BIT, UNPROTECTED REAL MODE FOR 320X200 RESOLUTION?
//I ASSUME IT USES THE INT 13 INTERRUPT TO DRAW STUFF TO SCREEN. I DONT NEED TO SAY THAT IT IS
//COMPLETELY UNSUPPORTED. ONE COULD USE ITS CONCEPTS HOWEVER.
//
//OF COURSE I AM NO EXPERT IN ANY OF THAT STUFF BUT ANYWAY I TRIED MY BEST TO TRANSLATE IT
//SOMEHOW TO D LANGUAGE. SPECIALLY THE "OUT" INSTRUCTION I HAVE NO IDEA WHAT IT DOES.
//OUT PROBABLY MEANS THE OUTPUT FORMAT.
//
//REMARKBLY I COULDNT UNDERSTAND SPECIALLY THINGS LIKE "4096-1". WHY NOT SIMPLY 4095?
//
//I AM ALSO USING EXTERN (C) FOR REASONS I CANT MYSELF EXPLAIN.
//IN THEORY IT DOESNT HAVE THE NEED TO BE C CALLING. BUT I TRIED TO KEEP IT
//AS FAITHFUL TO THE ORIGINAL AS POSSIBLE AND I ASSUME KEN USED C CONVENTION BACK THEN.
//ACTUALLY, DOES BASIC HAVE C CALLING? MAYBE PASCAL? WHATEVER. IF YOU KNOW, CHANGE IT.
//
//I MIGHT AS WELL BE DOING IT ALL WRONG. AND ACTUALLY, I TOTALLY BELIEVE I AM.
//THEREFORE I LEAVE THIS CODE AS IT IS UNTIL I BECOME SMART ENOUGH TO FIGURE STUFF LIKE THAT
//OUT.
//
//FINALLY IF YOU CAN DO ANYTHING FOR THAT, YOU ARE WELCOME TO.
//NOT THAT THIS CODE WILL BE OF A LOT OF USE. BUT FOR HOBBYISTS ITS ALWAYS INTERESTING.
//
//SIGNED: W. "UIRIAMU" F. M.

extern (C)
void translated() {
    //!SCREEN 13: DEF SEG = &HA000
    //SCREEN 13? SEG? MAYBE ITS MEANT TO BE asm{int 13} ???

    //DIM hei%(4096 - 1), col%(4096 - 1)
    float[4096-1] hei;
    float[4096-1] col;

    int x,y,z;

//!Generate palette
    /**OUT &H3C8, 0**/

    /*FOR z% = 0 TO 63:*/ /**OUT &H3C9, z%:  OUT &H3C9, z%:   OUT &H3C9, z% \ 2: NEXT z%**/
                                                                                //        |
    for (z=0;z<64;z++) {                                                        //        |
        //out?     <----------------------------------------------------------------------+
        //out?     <----------------------------------------------------------------------+
        //out?     <----------------------------------------------------------------------+
    }


//FOR z% = 0 TO 63: OUT &H3C9, z% \ 2: OUT &H3C9, z%: OUT &H3C9, z%: NEXT z%
    for (z=0;z<64;z++) {
        //out?
        //out?
        //out?

        //again?
    }

//!Generate interesting height & color maps
//p% = 0
//FOR y% = 0 TO 63
//   FOR x% = 0 TO 63
//      d% = 15 * 15 - ((x% AND 31) - 16) ^ 2 - ((y% AND 31) - 16) ^ 2
//      IF d% > 0 AND ((x% XOR y%) AND 32) THEN
//        hei%(p%) = 64 - SQR(d%): col%(p%) = (x% + y%) * .5
//      ELSE
//         hei%(p%) = 64: col%(p%) = (COS(x% * .2) + SIN(y% * .3)) * 3 + 88
//      END IF
//      p% = p% + 1
//   NEXT x%
//NEXT y%

    uint p = 0;

    for (y=0;y<64;y++) {
        for (x=0;x<64;x++) {
            float d = (15*15-((x && 31)-16)^2 - ((y && 31) -16)^2);
            if (d>0 && ((x^y)) && 32) {
                hei[p] = (64 - sqrt(d));
                col[p] = ((x+y)*0.5f);
            } else {
                hei[p] = 64;
                col[p] = ((cos(x *0.2f) + sin(y*0.3f)) * 3 + 88);
            }
            p+=1;
        }
    }

//! Initialize starting position
//posx& = 0: posy& = 0: posz& = 40 * 65536: ang = 0: horiz& = -50

    uint posx = 0;
    uint posy = 0;
    uint posz = 40* 65536;
    uint horiz = -50;
    int ang = 0;

//r160 = 1 / 160  ???????
    double r160 = (1/160);

//! Increment size
//dd& = 65536 * r160
    double dd = (65536 * r160);

//! Scan out 128 units
//de& = dd& * 128
    double de = (dd*128);

//sdz& = (100 - horiz&) * 65536 * r160
    double sdz = ((100-horiz) * 65536 * r160);

    //mistakes that came from the original and are being added below: >_>
    double dz = 0;
    int d = 0;
    int i = 0;
    float h = 0;


    short whiletest = 0; //this will serve as test for the DO below

//DO
    do {
        //cosang = COS(ang) * 65536: sinang = SIN(ang) * 65536
        //dx& = sinang + cosang: dxi& = -sinang * r160
        //dy& = sinang - cosang: dyi& = cosang * r160
        //   'For each column in 320*200 mode...
        //FOR sx% = 0 TO 319
        real cosang = cos(ang) * 65536;
        real sinang = sin(ang) * 65536;
        real dx = sinang + cosang;
        real dy = sinang - cosang;
        real dxi = -sinang * r160;
        real dyi = cosang * r160;

        //!for each column in 320x200 mode ???
        //FOR sx% = 0 TO 319
        for (int sx = 0;sx<320;sx++) {
            //! Fast ray trace! No *'s or /'s in here (\ 65536 is a shift)
            //x& = posx&: y& = posy&: z& = posz&: dz& = sdz&: p& = sx% + 63680
            //   FOR d& = 0 TO de& STEP dd&
            //      x& = x& + dx&: y& = y& + dy&: z& = z& + dz&
            //      i% = (((x& * 64) AND &HFC00000) + (y& AND &H3F0000)) \ 65536
            //      h& = hei%(i%) * 65536
            x = posx;
            y = posy;
            z = posz;
            dz = sdz;
            p = sx + 63680;

            //FOR d& = 0 TO de& STEP dd&
            for (d=0;d<=de;dd++) {
                x = x+cast(int)dx;
                y = y+cast(int)dy;
                z = z+cast(int)dz;
                i = (((x*64) && 0xFC00000) + (y && 0x3F0000));
                h = hei[i] * 65536;

                do {
                    /*
                    DO WHILE h& < z&
                    POKE p&, col%(i%): p& = p& - 320&
                    z& = z& - d&: dz& = dz& - dd&
                    LOOP
                    NEXT d&
                    dx& = dx& + dxi&: dy& = dy& + dyi&
                    */

                } while (h<z);

                /*
                //! Finish off rest of line
                DO WHILE p& >= 19200: POKE p&, 0: p& = p& - 320: LOOP
                NEXT sx%

                //! Move position & angle
                posx& = posx& + cosang * 4
                posy& = posy& + sinang * 4
                ang = ang + .02
                */
            }
        }

        whiletest++; //++ this only for testing as I stated at its declaration.
    } while (whiletest!=5); //LOOP WHILE INKEY$ = "" (using whiletest instead of this INKEY stuff)
}

//INFO: THE // COMMENTS INSIDE TRANSLATED() ARE ACTUAL ORIGINAL BASIC CODE.
